package com.zyao89.view.zloading.path;

import com.zyao89.view.zloading.ZLoadingBuilder;
import com.zyao89.view.zloading.util.FloatRange;
import com.zyao89.view.zloading.util.NumCalcUtil;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.render.*;
import ohos.agp.utils.Color;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;

/**
 * SearchPathBuilder
 *
 * @author jjy
 * @since 2021-03-22
 */
public class SearchPathBuilder extends ZLoadingBuilder
{
    private final String TAG = "Zloading SearchPathBuilder";

    // 最终阶段
    private static final int FINAL_STATE = 3;

    // 当前动画阶段
    private int mCurrAnimatorState = 0;
    private float mR;
    private Paint mPaint;
    private Path mPath;
    private Path mPathZoom;
    private PathMeasure mPathMeasure;
    private Path mDrawPath;

    @Override
    protected void initParams(Context context, Color color) {
        mR = getAllSize();
        initPaint(color);
        initPathMeasure();
        initPaths();
    }

    private void initPaint(Color color) {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE_STYLE);
        mPaint.setStrokeWidth(15);
        mPaint.setColor(color);
        mPaint.setDither(true);
        mPaint.setFilterBitmap(true);
        mPaint.setStrokeCap(Paint.StrokeCap.ROUND_CAP);
        mPaint.setStrokeJoin(Paint.Join.ROUND_JOIN);
    }

    private void initPaths() {
        float r = mR * 0.4f;
        mPath = new Path();
        mPath.addArc(new RectFloat(NumCalcUtil.subtract(getViewCenterX(), mR), NumCalcUtil.subtract(getViewCenterY(), mR), NumCalcUtil.add(getViewCenterX(), mR), NumCalcUtil.add(getViewCenterY(), mR)), 45, 359.9f);
        mPathMeasure.setPath(mPath, false);
        float[] pos = new float[2];
        mPathMeasure.getPosTan(0, pos, null);

        mPathZoom = new Path();
        mPathZoom.addArc(new RectFloat(NumCalcUtil.subtract(getViewCenterX(), r), NumCalcUtil.subtract(getViewCenterY(), r), NumCalcUtil.add(getViewCenterX(), r), NumCalcUtil.add(getViewCenterY(), r)), 45, 359.9f);
        mPathZoom.lineTo(pos[0], pos[1]);
    }

    private void initPathMeasure() {
        mDrawPath = new Path();
        mPathMeasure = new PathMeasure(mDrawPath, false);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawPath(mDrawPath, mPaint);
    }

    @Override
    protected void setAlpha(int alpha)
    {
        mPaint.setAlpha(alpha);
    }

    @Override
    protected void prepareStart(AnimatorValue floatValueAnimator) {
        floatValueAnimator.setCurveType(Animator.CurveType.DECELERATE);
    }

    @Override
    protected void prepareEnd() {

    }

    @Override
    protected void computeUpdateValue(AnimatorValue animation, @FloatRange(from = 0.0, to = 1.0)float animatedValue) {
        switch (mCurrAnimatorState)
        {
            case 0:
            case 1:
                resetDrawPath();
                mPathMeasure.setPath(mPath, false);
                float stop = mPathMeasure.getLength() * animatedValue;
                float start = (float) (stop - ((0.5 - Math.abs(animatedValue - 0.5)) * 200f));
                mPathMeasure.getSegment(start, stop, mDrawPath, true);
                break;
            case 2:
                resetDrawPath();
                mPathMeasure.setPath(mPath, false);
                stop = mPathMeasure.getLength() * animatedValue;
                start = 0;
                mPathMeasure.getSegment(start, stop, mDrawPath, true);
                break;
            case 3:
                mPathMeasure.setPath(mPathZoom, false);
                stop = mPathMeasure.getLength();
                start = stop * NumCalcUtil.subtract(1, animatedValue);
                mPathMeasure.getSegment(start, stop, mDrawPath, true);
                break;
            default:
                break;
        }
    }

    @Override
    public void onRepeat(Animator animator) {
        if (++mCurrAnimatorState > FINAL_STATE)
        {
            // 还原到第一阶段
            mCurrAnimatorState = 0;
        }
    }

    @Override
    protected void setColorFilter(ColorFilter colorFilter)
    {
        mPaint.setColorFilter(colorFilter);
    }

    private void resetDrawPath() {
        mDrawPath.reset();
        mDrawPath.lineTo(0, 0);
    }
}
